// generator 是生成器 用来生成 迭代器 (想要了解generator怎么实现的？generator-runtime generator简单实现)
//生成器的特点是 函数名声明有个* 另外里面有yield

//TODO 迭代器执行机制查看generator.png
//一次迭代，会执行到下一次yield
function * read(){
  console.log(1);
  yield 'a';
  console.log(2);
  yield 'b';
  console.log(3);
}

let it = read();// iterator
console.log(it.next()); /** {value: a, done: false} 其中的value就是yield的值*/
console.log(it.next()); // {value: b, done: false}
console.log(it.next()); // {value: undefined, done: true} true->迭代完了


console.log('it2--- --- ---');
//除第一次next以外每次next都可以传递参数进这一次迭代，以供使用
function * buy(arg){
  console.log('buy arg:',arg); //输出下面传入的123
  let a/** ←第二次it.next时传入的值(第一次next不接受值)*/ = yield 1;
  //↑ 不是yield出去的1, 而是下一次.next()接受的值, 这样的设计, 如果yield出去的是一个promise, 我们恰好能利用这样的设计 在这个promise状态转换后(.then),将promise得到的结果作为参数传入 下一次.next, 这样就简化了promise的书写流程, 简直就像写同步代码一样 (只要利用某个插件帮我们自动完成这件事的话 ---> co)
  console.log('a:',a); //a: world

  let b = yield 2;
  console.log('b:',b); //b: ahhh
  return b; /** ←最后return的会作为最后一次it.next()返回值的.value*/
}

let it2 = buy(123);

// 第一次的next传递参数是无效的, 要传应该在生成迭代器时 即上面 let it2 = buy(123)
console.log(it2.next('hello')); // { value: 1, done: false }

//buy arg: 123
// { value: 1, done: false }
//a: world

console.log(it2.next('world')); // { value: 2, done: false }

//b: ahhh

console.log(it2.next('ahhh')); // { value: 'ahhh', done: true }
